package com.carloha.finance.tool;

import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.itextpdf.text.Chunk;
import com.itextpdf.text.Document;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Image;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import sample.web.beetl.PdfPTableData;
import sample.web.beetl.PdfPTableRow;

/**
 * pdf报告
 * @author 报告
 * @date 2019-7-14
 */
public class PdfReport {
	static final Logger LOG = LoggerFactory.getLogger(PdfReport.class);
	private static String fontName = "C:/Windows/Fonts/SIMYOU.TTF";
	
	//读取excel表格数据
	public static List<NailBean> readExcel(String file){
		if(file == null || "".equals(file.trim())) {
			throw new RuntimeException("文件名不能为空");
		}
		//校验文件必须为excel
		try {
			InputStream inputStream = new FileInputStream(file);
			FileType ft = checkFileType(inputStream,file);			
			if(! ft.toString().toUpperCase().startsWith("XLS")) {
				throw new RuntimeException("读取excel表格文件不合法");
			}
		}catch(Exception e) {
			LOG.error(e.getMessage(), e.getCause());
		}
		
		List<List<String>> list = XlsUtil.readExcel(file);		
		int size = list.size();
		List<NailBean> result = new ArrayList<NailBean>();
		if(size > 1) {			
			for(int i = 1; i < size ; i++) {
				NailBean bean = toNailBean(list.get(i));
				if(bean != null) {
					result.add(bean);	
				}				
			}
		}		
		return result;
	}
    //list数据转钉钉
	private static NailBean toNailBean(List<String> param) {
		if(param == null || param.size() == 0) {
			return null;	
		}
		NailBean bean = new NailBean();
		bean.setApprovalNumber(param.get(0));
		bean.setTitle(param.get(1));
		bean.setApprovalStatus(param.get(2));
		bean.setApprovalResult(param.get(3));
		bean.setLaunchTime(param.get(4));
		bean.setCompleteTime(param.get(5));
		bean.setTimeConsuming(param.get(6));
		bean.setInitiatorNumber(param.get(7));
		bean.setInitiatorUserId(param.get(8));
		bean.setInitiatorName(param.get(9));
		bean.setInitiatorDepartment(param.get(10));
		bean.setHistoryInitiatorName(param.get(11));
		bean.setApprovalRecords(param.get(12));
		bean.setCurrentHandlerName(param.get(13));
		bean.setDetails(param.get(14));
		bean.setAmount(param.get(15));
		bean.setPurchaseDate(param.get(16));
		bean.setCategory(param.get(17));
		bean.setName(param.get(18));
		bean.setNumber(param.get(19));
		bean.setPurpose(param.get(20));
		bean.setCostDetails(param.get(21));
		bean.setPicture(param.get(22));
		bean.setAtth(param.get(23));		
		return bean;
	}
	
	//检查文件类型
	private static FileType checkFileType(InputStream inStream,String fileName) {
		FileType ft = null;
		try {
			String ext = fileName.substring(fileName.lastIndexOf(".") + 1);
			byte[] file_buff = CarlohaFileUtil.copy(inStream);
			ft = FileTypeJudge.getType(file_buff);
			if (ft == null) {
				throw new RuntimeException("不能识别的文件类型");
			}if (ft.notMatch(ext)) {
				throw new RuntimeException("你篡改了文件后缀名");
			}
					
		}catch(Exception e) {
			LOG.error(e.getMessage(), e.getCause());
		}
		return ft;	
		
	}
	
	/**
	 * 生成pdf报告文件
	 * @param fileName
	 * @param param
	 */
	public static void createPdfReport(String fileName,List<NailBean> param) {
		//卡洛哈（中国）报销记录_20190601_20190710.docx		
		Document doc = PdfUtil.createPdfDocument();		
		PdfWriter writer = PdfUtil.getPdfWriter(doc, getReportFileName(fileName));
		// 打开文档，只有打开后才能往里面加东西
		doc.open();
		// 设置作者
		doc.addAuthor("草原狼");
		// 设置创建者
		doc.addCreator("草原狼");
		// 设置主题
		doc.addSubject("卡洛哈（中国）财务报销记录");
		// 设置标题
		doc.addTitle("卡洛哈（中国）财务报销记录");		
		try {			
			//添加主标题
			addCenterTitle(doc,"卡洛哈（中国）财务报销记录");
			newline(doc,1);
			//添加日期标题
			addCenterTitle(doc,getDateTitle(fileName));
			//newline(doc,3);			
			addContent(doc,param);			
		} catch (Exception e) {
			LOG.error(e.getMessage(), e.getCause());
		}
		System.out.println("生成报告结束");
		PdfUtil.close(doc, writer);
	}
	
	/**
	 * 添加文档内容
	 * @param doc
	 * @param param
	 */
	private static void addContent(Document doc,List<NailBean> param) throws Exception {
		int size = param.size();
		for(int i = 0 ; i < size ;  i++) {							
			newline(doc,1);
			int num = i +1;
			addNumIndex(doc,num);			
			newline(doc,1);
			//插入表格
			//createTable(doc);
			createTable(doc,param.get(i));
			//插入图片
			addTableImg(doc,param.get(i));	
			doc.newPage();
		}
	}
	
	/**
	 * 插入表格的图片
	 */
	private static void addTableImg(Document doc,NailBean bean) throws Exception {
		String pic = bean.getPicture();
		String newLine = System.getProperty("line.separator");
		String[] pics = pic.split(newLine);
		LOG.info("Lines:"+pics.length);
		for(String url : pics) {
			addImg(doc,url);	
		}
	}
	
	
	/**
	 * 添加网络图片
	 * @param doc
	 * @throws Exception
	 */
	private static void addImg(Document doc,String url) throws Exception {
		Image img = PdfUtil.getURLImg(url);
		Image picture = PdfUtil.percentImage(img, 1);
		PdfUtil.addImg(doc, picture);			
	}
	
	/**
	 * 创建表格
	 * @param doc
	 * @param param
	 * @throws Exception
	 */
	private static void createTable(Document doc,NailBean param) throws Exception{		
		float[] widths = {120, 405};
		PdfPTable table = new PdfPTable(widths);
		table.setTotalWidth(525);
		table.setLockedWidth(true);
		table.setHorizontalAlignment(Element.ALIGN_CENTER);
		PdfPTableData datas = getTableData(param);
		List<PdfPTableRow> rows = datas.getData();
		for(PdfPTableRow row : rows) {
			PdfPCell pdfCellHead = new PdfPCell(); 
	        Paragraph paragraph = new Paragraph(row.getHead(), getPdfChineseFont());
	        pdfCellHead.setPhrase(paragraph);
	        table.addCell(pdfCellHead);
	        
	        PdfPCell pdfCellValue = new PdfPCell(); 
	        Paragraph paragraph2 = new Paragraph(row.getValue(), getPdfChineseFont());
	        pdfCellValue.setPhrase(paragraph2);
	        table.addCell(pdfCellValue);
			
		}		 
		doc.add(table); //pdf文档中加入table
	}
	
	/**
	 * 获取表格数据
	 * @param param
	 * @return
	 */
	private static PdfPTableData getTableData(NailBean param){
		PdfPTableData datas = new PdfPTableData();			
		List<PdfPTableRow> rows = datas.getData();
		PdfPTableRow row1 = new PdfPTableRow();
		row1.setHead("审批编号");
		row1.setValue(param.getApprovalNumber());
		rows.add(row1);
		
		PdfPTableRow row2 = new PdfPTableRow();
		row2.setHead("购买日期");
		
		row2.setValue(param.getPurchaseDate());
		rows.add(row2);
		
		PdfPTableRow row3 = new PdfPTableRow();
		row3.setHead("发起人UserID");
		row3.setValue(param.getInitiatorUserId());
		rows.add(row3);
		
		
		PdfPTableRow row4 = new PdfPTableRow();
		row4.setHead("发起人姓名");
		row4.setValue(param.getInitiatorName());
		rows.add(row4);
		
		
		PdfPTableRow row5 = new PdfPTableRow();
		row5.setHead("发起人部门");
		row5.setValue(param.getInitiatorDepartment());
		rows.add(row5);
		
		
		PdfPTableRow row6 = new PdfPTableRow();
		row6.setHead("审批记录");
		row6.setValue(param.getApprovalResult());
		rows.add(row6);
		
		
		PdfPTableRow row7 = new PdfPTableRow();
		row7.setHead("报销金额(元)");
		row7.setValue(param.getAmount());
		rows.add(row7);
		
		PdfPTableRow row8 = new PdfPTableRow();
		row8.setHead("报销类别");
		row8.setValue(param.getCategory());
		rows.add(row8);
		
		PdfPTableRow row9 = new PdfPTableRow();
		row9.setHead("名称");
		row9.setValue(param.getName());
		rows.add(row9);
		
		PdfPTableRow row10 = new PdfPTableRow();
		row10.setHead("数量");
		row10.setValue(param.getNumber());
		rows.add(row10);
		
		PdfPTableRow row11 = new PdfPTableRow();
		row11.setHead("用途");
		row11.setValue(param.getPurpose());
		rows.add(row11);
		
		PdfPTableRow row12 = new PdfPTableRow();
		row12.setHead("费用明细");
		row12.setValue(param.getDetails());
		rows.add(row12);
		
		PdfPTableRow row13 = new PdfPTableRow();
		row13.setHead("图片");
		row13.setValue(param.getPicture());
		rows.add(row13);
		
		PdfPTableRow row14 = new PdfPTableRow();
		row14.setHead("附件");
		row14.setValue(param.getAtth());
		rows.add(row14);		
		return datas;
	}
	
	public static Font getPdfChineseFont() throws Exception {
		BaseFont baseFont = BaseFont.createFont(fontName,BaseFont.IDENTITY_H,BaseFont.NOT_EMBEDDED);  
		Font font = new Font(baseFont);		
		return font;
	}	
	
	/**
	 * 构造标题
	 * @param doc
	 * @param content
	 * @return
	 * @throws Exception
	 */
	private static Paragraph buildTitle(Document doc,String content) throws Exception {
		BaseFont baseFont = BaseFont.createFont(fontName,BaseFont.IDENTITY_H,BaseFont.NOT_EMBEDDED);  
		Font font = new Font(baseFont);		
		Paragraph title = new Paragraph();
		Chunk c = new Chunk(content,font);
		setTitleFont(title.getFont(),24);
		title.add(c);		
		return title;
	}
	/**
	 * 添加居中标题
	 * @param doc
	 * @throws Exception
	 */
	private static void addCenterTitle(Document doc,String content) throws Exception {
		Paragraph title = buildTitle(doc,content);	
		setParagraphAlignCenter(title);
		doc.add(title);		
	}
	
	/**
	 * 添加居左标题
	 * @param doc
	 * @param content
	 * @throws Exception
	 */
	private static void addLeftTitle(Document doc,String content) throws Exception {
		Paragraph title = buildTitle(doc,content);	
		setParagraphAlignLeft(title);
		doc.add(title);	
	}
	
	/**
	 * 从文件名中提取数字标题
	 * @param fileName
	 * @return
	 */
	private static String getDateTitle(String fileName) {
		if(fileName == null || "".equals(fileName.trim())) {
			throw new RuntimeException("excel表格数据文件名为空"+fileName);
		}
		int endIndex = fileName.lastIndexOf(".");
		String tmp = fileName.substring(0, endIndex);
		int beginIndex = tmp.indexOf("报销记录_") + 5;
		String result = tmp.substring(beginIndex);
		LOG.info(result);
		return result;
	}
	
	/**
	 * 设置数字标题
	 * @param doc
	 * @param content
	 * @throws Exception
	 */
	private static void addNumIndex(Document doc,int content) throws Exception {
		addLeftTitle(doc,""+content);
	}
	
	/**
	 * 设置标题字体
	 */
	private static void setTitleFont(Font font,int size) {
		font.setSize(size);
		font.setStyle(Font.BOLD);
	}
	
	/**
	 * 设置居中
	 */
	private static void setParagraphAlignCenter(Paragraph g) {
		g.setAlignment(Element.ALIGN_CENTER);
	}
	
	/**
	 * 设置居左
	 */
	private static void setParagraphAlignLeft(Paragraph g) {
		g.setAlignment(Element.ALIGN_LEFT);		
	}
	
	/**
	 * 添加换行
	 * 
	 * @param doc
	 */
	private static void newline(Document doc, int line) {
		try {
			Font font = PdfUtil.getFont();
			for (int i = 0; i < line; i++) {
				doc.add(new Paragraph("\n\r", font));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

	}
	
	public static String getReportFileName(String file) {	
		int pos = file.indexOf(".");
		String rename = file.substring(0, pos) + ".pdf";		
		return rename;
	}	
	
	
	/**
	 * 读取excel数据
	 */
	public static List<NailBean> readExcelData(String file) {		
		List<NailBean> list = readExcel(file);
		return list;
	}
	
	/**
	 * 生成pdf报告入口方法
	 * @param fileName
	 * @param param
	 */
	public static void createPdfReport(String fileName) {
		List<NailBean> param = readExcelData(fileName);		
		PdfReport.createPdfReport(fileName,param);
	}
	public static void main(String[] args) {
		String file = "G:/tmp1/卡洛哈（中国）报销记录_20190601_20190717.xls";		
		List<NailBean> param = readExcelData(file);		
		PdfReport.createPdfReport(file,param);
	}
	
}
